﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Algoritmia.DataStructures.Maps;

namespace Algoritmia.DataStructures.Digraphs
{
    public class AdjacencyMatrixDigraph : AdjacencyDigraph<int>
    {
        public AdjacencyMatrixDigraph(IEnumerable<int> vertices = null, IEnumerable<Tuple<int, int>> edges = null,
                                      bool directed = true)
            : base(vertices, edges, directed,(a,b) => a == b,
                   items => new IntKeyMap<Sets.ISet<int>>(capacity: items.Max() +1),  
                   items => new Sets.IntSet(capacity: items.Max() + 1),
                   (map, key) =>
                       {
                           var intKeyMap = (IntKeyMap<Sets.ISet<int>>) map;
                           if (intKeyMap.Capacity <= key )
                           {
                               intKeyMap.Capacity = key + 1;
                           }
                           return map;
                       },
                   (set, key) =>
                       {
                           var intSet = (Sets.IntSet) set;
                           if (intSet.Capacity <= key )
                           {
                               intSet.Capacity = key + 1;

                           }
                           return set;
                       }
            )
        {
        }

        public AdjacencyMatrixDigraph(IEnumerable<KeyValuePair<int, IEnumerable<int>>> edges,
                                      bool directed = true)
            : base(edges, directed, (a,b) => a == b,
                   items => new IntKeyMap<Sets.ISet<int>>(capacity: items.Max() + 1),  
                   items => new Sets.IntSet(capacity: items.Max() + 1),
                   (map, key) =>
                   {
                       var intKeyMap = (IntKeyMap<Sets.ISet<int>>)map;
                       if (intKeyMap.Capacity <= key)
                       {
                           intKeyMap.Capacity = key + 1;
                       }
                       return map;
                   },
                   (set, key) =>
                   {
                       var intSet = (Sets.IntSet)set;
                       if (intSet.Capacity <= key)
                       {
                           intSet.Capacity = key + 1;

                       }
                       return set;
                   }
            )
        {
        }

        protected override void AddVertex(int vertex)
        {
            if (!_succs.Contains(vertex))
            {
                var intKeyMapSuccs = (IntKeyMap<Sets.ISet<int>>) _succs;
                if ( vertex >= intKeyMapSuccs.Capacity)
                {
                    intKeyMapSuccs.Capacity = vertex + 1;
                    foreach(var key in _succs.Keys())
                    {
                        ((Sets.IntSet)_succs[key]).Capacity = vertex + 1;
                    }
                }
                
                _succs[vertex] = _createSet(V);
            }
        }

        public override string ToString()
        {
            StringBuilder sb = new StringBuilder(String.Format("{0} [",GetType().Name));
            foreach(var kv in _succs)
            {
                sb.Append(String.Format("( {0} , {1} ) ,",kv.Key,kv.Value));
            }
            sb.Append("]");
            return sb.ToString();
        }
    }
}
